package com.yx.changdao.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yx.changdao.common.data.Pager;
import com.yx.changdao.common.data.Result;
import com.yx.changdao.common.entity.*;
import com.yx.changdao.common.exception.AlertException;
import com.yx.changdao.common.mapper.SysRoleMapper;
import com.yx.changdao.common.utils.SysConst;
import com.yx.changdao.common.utils.SysUtils;
import com.yx.changdao.common.vo.RolePermissionSetVo;
import com.yx.changdao.common.vo.RolePermissionVo;
import com.yx.changdao.service.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 权限设置
 * @Auther: zhangcongzhen
 * @create 2020/4/17
 */
@Service
public class SysPermissionSetServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysPermissionSetService {

    @Autowired
    SysRolePermissionService sysRolePermissionService;
    @Autowired
    SysMenuService sysMenuService;
    @Autowired
    SysRoleService sysRoleService;
    @Autowired
    SysUserRoleService sysUserRoleService;
    @Autowired
    SysUserService sysUserService;
    /**
     * 权限设置权限列表
     */
    @Override
    public Result getResult(Long page, Integer limit) {
        if (limit == null) {
            limit = SysConst.LIMIT_PAGE;
        }
        // 分页配置
        Page<SysRole> pager = new Page<>(page, limit);
        // 根据请求解析条件。
        QueryWrapper<SysRole> qw = SysUtils.autoCnd(SysRole.class);
        // 获取分页结果集。
        Page<SysRole> list = this.page(pager, qw.ne(SysRole.ROLE_ID,SysConst.SYS_ROLE));
        if (!list.getRecords().isEmpty()) {
            for (SysRole role : list.getRecords()) {
                StringBuffer sb = new StringBuffer();
                // 当前角色的权限
                List<SysPermission> permissions = sysRolePermissionService.getRolePermissions(role.getRoleId());
                if(permissions.isEmpty()){
                    continue;
                }
                // 权限id的集合
                List<String> permIds = permissions.stream().map(perm -> perm.getPermId()).collect(Collectors.toList());
                // 获取角色拥有的一级菜单列表
                List<SysMenu> parentMenus = sysMenuService.list(new QueryWrapper<SysMenu>().in(SysMenu.PERMISSION_ID, permIds).eq(SysMenu.MENU_PARENT, "0"));
                for (SysMenu menu : parentMenus) {
                    StringBuffer child = new StringBuffer();
                    QueryWrapper<SysMenu> childmMenuQw = new QueryWrapper<SysMenu>()
                            .in(SysMenu.PERMISSION_ID, permIds)
                            .eq(SysMenu.MENU_PARENT, menu.getMenuId())
                            .orderByAsc(SysMenu.MENU_SORT).select(SysMenu.MENU_NAME);
                    //当前父级菜单下的子菜单
                    List<SysMenu> childmMenus = sysMenuService.list(childmMenuQw);
                    for (SysMenu childmMenu : childmMenus) {
                        child.append(childmMenu.getMenuName()).append("/");
                    }
                    sb.append(menu.getMenuName());
                    if (child.length() > 0) {
                        String childMenus = StringUtils.substring(child.toString(), 0, child.length() - 1);
                        sb.append("(").append(childMenus).append(")  ");
                    }
                }
                role.setMenuNames(String.valueOf(sb));
            }
        }
        Map<String, Object> map = new HashMap<>();
        map.put("list", list.getRecords());
        map.put("pager", new Pager(list));
        return Result.ok().data(map);
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public Result update(RolePermissionSetVo rolePermissionSetVo) throws AlertException {
        int count = sysRoleService.count(new QueryWrapper<SysRole>().eq(SysRole.ROLE_NAME, rolePermissionSetVo.getRoleName()).ne(SysRole.ROLE_ID, rolePermissionSetVo.getRoleId()));
        if (count > 0) {
            throw new AlertException("角色名称已存在");
        }
        sysRolePermissionService.delRoleAllPermissions(rolePermissionSetVo.getRoleId());
        sysRoleService.update(new UpdateWrapper<SysRole>().set(SysRole.ROLE_NAME,rolePermissionSetVo.getRoleName()).eq(SysRole.ROLE_ID,rolePermissionSetVo.getRoleId()));
        //要给角色添加的权限  权限去重复，防止多菜单共用一个权限
        List<String> permIds = rolePermissionSetVo.getPermIds().stream().distinct().collect(Collectors.toList());
        for (String permId : permIds) {
            saveRolePerm(rolePermissionSetVo.getRoleId(), permId);
        }
        return Result.ok("角色修改成功");
    }


    @Override
    @Transactional(rollbackFor = {Exception.class})
    public Result add(RolePermissionSetVo rolePermissionSetVo) throws AlertException {
        int count = sysRoleService.count(new QueryWrapper<SysRole>().eq(SysRole.ROLE_NAME, rolePermissionSetVo.getRoleName()));
        if (count > 0) {
            throw new AlertException("角色名称已存在");
        }
        //保存角色
        SysRole role = new SysRole();
        role.setRoleName(rolePermissionSetVo.getRoleName());
        SysRole sysRole = sysRoleService.addRole(role);
        if (sysRole == null) {
            throw new AlertException("角色添加失败");
        }
        // 要给角色添加的权限
        List<String> permIds = rolePermissionSetVo.getPermIds();
        List<String> collect = permIds.stream().distinct().collect(Collectors.toList());

        for (String permId : collect) {
            int rpCount = sysRolePermissionService.count(new QueryWrapper<SysRolePermission>()
                    .eq(SysRolePermission.ROLE_ID, role.getRoleId()).eq(SysRolePermission.PERM_ID, permId));
            if (rpCount == 0){
                saveRolePerm(sysRole.getRoleId(), permId);
            }
        }
        return Result.ok("角色添加成功");
    }



    private void saveRolePerm(String roleId, String permId) throws AlertException {
        SysRolePermission rolePermission = new SysRolePermission();
        rolePermission.setPermId(permId);
        rolePermission.setRoleId(roleId);
        sysRolePermissionService.addRolePermission(rolePermission);
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public Result delete(String roleId) throws AlertException {
        if(SysConst.SYS_ROLE.equals(roleId)){
            throw new AlertException("当前角色为超级管理员，不可删除");
        }
        if (0 < this.sysUserRoleService.count( new QueryWrapper<SysUserRole>().lambda().eq(SysUserRole::getRoleId, roleId))) {
            throw new AlertException("当前角色正在被使用，不可删除");
        }
        // 删除角色和他所有权限。
        Boolean b = this.sysRoleService.delRole(roleId);
        if (!b) {
            throw new AlertException("角色删除失败");
        }
        return Result.ok("删除角色成功");
    }

    @Override
    public Result getRolePermission(String roleId) throws AlertException {
        RolePermissionVo rolePermissionVo = new RolePermissionVo();
        ArrayList<String> parentPerms = new ArrayList<>();
        ArrayList<String> childPerms = new ArrayList<>();
        SysRole role = sysRoleService.getRole(roleId);
        if (Objects.isNull(role)) {
            throw new AlertException("角色不存在");
        }
        BeanUtils.copyProperties(role, rolePermissionVo);
        List<SysPermission> permissions = sysRolePermissionService.getRolePermissions(roleId);
        if(!permissions.isEmpty()){
            List<String> collect = permissions.stream().map(perm -> perm.getPermId()).collect(Collectors.toList());
            List<SysMenu> menus = sysMenuService.list(new QueryWrapper<SysMenu>().in(SysMenu.PERMISSION_ID, collect));
            // 0为父菜单权限  其他为子菜单权限
            for (SysMenu menu:menus) {
                if("0".equals(menu.getMenuParent())){
                    parentPerms.add(menu.getPermissionId());
                }else {
                    childPerms.add(menu.getPermissionId());
                }
            }
        }
        rolePermissionVo.setChildPerms(childPerms);
        rolePermissionVo.setParentPerms(parentPerms);
        return Result.ok().data(rolePermissionVo);
    }
}
